package com.wugh.fast.kernel.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Calendar;
import java.util.Date;

/**
 * 说明:
 *
 * @author wugh
 * @date 2018-12-04 11:34
 * @see cn.hutool.core.date.DateUtil
 * @deprecated 请使用hutool的DateUtil
 */
@Deprecated
public class DateUtils {
    /**
     * 时间格式(yyyy-MM-dd)
     */
    public final static String DATE_PATTERN = "yyyy-MM-dd";
    public final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(DATE_PATTERN);
    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    private final static ZoneId localZone = ZoneId.systemDefault();

    /**
     * 每天小时数
     */
    private static final int HOURS_PER_DAY = 24;

    /**
     * 每小时分钟数
     */
    private static final int MINUTES_PER_HOUR = 60;
    /**
     * 每天分钟数
     */
    private static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY;
    /**
     * 每分钟秒数
     */
    private static final int SECONDS_PER_MINUTE = 60;
    /**
     * 每小时秒
     */
    private static final int SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
    /**
     * 每天秒
     */
    private static final int SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;

    /**
     * 每天秒
     */
    private static final int MILLISECONDS_PER_DAY = SECONDS_PER_DAY * 1000;

    /**
     * 使用默认格式{@link DateUtils#DATE_PATTERN}时间格式化
     *
     * @param date
     * @return
     */
    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    /**
     * 自动解析时间字符串
     * <pre>
     *     目前支持格式:
     *          yyyy-MM-dd
     *          yyyy-MM-dd HH:mm:ss
     *          yyyy/MM/dd
     *          yyyy/MM/dd HH:mm:ss
     *          yyyy年MM月dd日 HH时mm分ss秒
     *          yyyy年MM月dd日
     *          yyyyMMdd hh:mm:ss
     *          yyyyMMdd
     * </pre>
     *
     * @param format
     * @return
     */
    public static Date parse(String format) {
        if (StringUtils.isBlank(format)) {
            return null;
        }
        try {
            return org.apache.commons.lang3.time.DateUtils.parseDate(format,
                    DateUtils.DATE_PATTERN, DateUtils.DATE_TIME_PATTERN,
                    "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss",
                    "yyyy年MM月dd日 HH时mm分ss秒", "yyyy年MM月dd日",
                    "yyyyMMdd", "yyyyMMdd HH:mm:ss"
            );
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 指定格式解析时间字符串
     *
     * @param format
     * @param pattern
     * @return
     */
    public static Date parse(String format, String pattern) {
        try {
            return org.apache.commons.lang3.time.DateUtils.parseDate(format, pattern);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 指定格式格式化日期
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String format(Date date, String pattern) {
        if (date != null) {
            return DateFormatUtils.format(date, pattern);
        }
        return null;
    }

    /**
     * 把date转化成LocalDate
     *
     * @param date
     * @return
     */
    public static LocalDate date2LocalDate(Date date) {
        if (date == null) {
            return null;
        }
        Instant instant = date.toInstant();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, localZone);
        return localDateTime.toLocalDate();
    }

    /**
     * localDate转化成Date
     *
     * @param localDate
     * @return
     */
    public static Date localDate2Date(LocalDate localDate) {
        if (localDate == null) {
            return null;
        }
        Instant instant = localDate.atStartOfDay(localZone).toInstant();
        return Date.from(instant);
    }

    // 获得当前月--开始日期
    public static Date getMinMonthDate(String date) {
        return getMinMonthDate(parse(date));
    }

    // 获得当前月--开始日期
    public static Date getMinMonthDate(String date, int month) {
        return getMinMonthDate(parse(date), month);
    }

    // 获得当前月--结束日期
    public static Date getMaxMonthDate(String date) {
        return getMaxMonthDate(parse(date));
    }

    public static Date getMaxMonthDate(String date, int month) {
        return getMaxMonthDate(parse(date), month);
    }

    // 获得当前月--开始日期
    public static Date getMinMonthDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        clearHourMinSec(calendar);
        return calendar.getTime();
    }

    // 获得当前月--开始日期
    public static Date getMinMonthDate(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        clearHourMinSec(calendar);
        return calendar.getTime();
    }

    // 获得当前月--结束日期
    public static Date getMaxMonthDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        clearHourMinSec(calendar);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }


    public static Date getMaxMonthDate(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        setMaxHourMinSec(calendar);
        return calendar.getTime();
    }

    public static Date getYesterday() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        clearHourMinSec(calendar);
        return calendar.getTime();
    }

    /**
     * 当前周的开始时间(周一)
     *
     * @param date
     * @param week
     * @return
     */
    public static Calendar getMinWeekCalendar(Date date, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.WEEK_OF_YEAR, week);
        // 距离周一为几天
        int d = 0;
        int duration = calendar.get(Calendar.DAY_OF_WEEK);
        // 该周的第几天,周日为 1
        if (duration == Calendar.SUNDAY) {
            d = -6;
        } else {
            d = 2 - duration;
        }
        calendar.add(Calendar.DAY_OF_WEEK, d);
        clearHourMinSec(calendar);
        return calendar;
    }

    public static Date getMinWeekDate(Date date, int week) {
        return getMinWeekCalendar(date, week).getTime();
    }

    public static Date getMinWeekDate(int week) {
        return getMinWeekDate(new Date(), week);
    }

    public static Date getMinWeekDate() {
        return getMinWeekDate(new Date(), 0);
    }

    /**
     * 当前周的结束时间(周日)
     *
     * @param date
     * @param week
     * @return
     */
    public static Date getMaxWeekDate(Date date, int week) {
        Calendar calendar = getMinWeekCalendar(date, week);
        calendar.add(Calendar.DAY_OF_WEEK, 6);
        setMaxHourMinSec(calendar);
        return calendar.getTime();
    }

    public static Date getMaxWeekDate(int week) {
        return getMaxWeekDate(new Date(), week);
    }

    public static Date getMaxWeekDate() {
        return getMaxWeekDate(new Date(), 0);
    }

    /**
     * 获取当前天开始时间
     *
     * @return
     */
    public static Date getMinDayDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        clearHourMinSec(calendar);
        return calendar.getTime();
    }

    /**
     * 获取当前天结束时间
     *
     * @return
     */
    public static Date getMaxDayDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        setMaxHourMinSec(calendar);
        return calendar.getTime();
    }

    /**
     * 获取当前天结束时间
     *
     * @return
     */
    public static Date getMinDayDate(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, days);
        clearHourMinSec(calendar);
        return calendar.getTime();
    }


    public static Date getMaxDayDate() {
        return getMaxDayDate(new Date());
    }

    public static Date getMinDayDate() {
        return getMinDayDate(new Date());
    }

    private static void clearHourMinSec(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    private static void setMaxHourMinSec(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
    }


    /**
     * 获取时间差(天数)
     *
     * @param begin 开始时间
     * @param end   结束时间
     * @return
     */
    public static int timeDifference(Date begin, Date end) {
        if (begin == null || end == null) {
            return 0;
        }
        Calendar beginCalendar = Calendar.getInstance();
        beginCalendar.setTime(begin);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(end);
        clearHourMinSec(beginCalendar);
        clearHourMinSec(endCalendar);
        long diff = endCalendar.getTimeInMillis() - beginCalendar.getTimeInMillis();
        return (int) (diff / MILLISECONDS_PER_DAY);
    }

}
